var MODELO = {

    Tienda : function(nombreTienda) {
        this._className = "Tienda";
        this.nombreTienda = nombreTienda;
        this.categoriasArticulos = new MODELO.Categorias();                
		
        //Observe que también podemos poner la adición de elementos en la propia tienda en vez de en las clases
        //Importante: No estoy retornando el objeto al que se añaden las categorías, sino el objeto que estoy añadiendo
        //ya que el que llama al método no tiene una referencia a él.
        this.addCategoria = function (id, nombre) {
            var categoria = new MODELO.Categoria(id, nombre);
            this.categoriasArticulos.addElemento(categoria);
            return categoria;
        }
        
        this.total = ko.computed(function() {
            var totalPedido = 0;
            this.categoriasArticulos.elementos().forEach(
                function(categoria) {
                    categoria.elementos().forEach(
                        function(articulo) {                                             
                            totalPedido += parseFloat(articulo.subtotal());  
                        }
                        );
                }
                );
            return parseFloat(totalPedido).toFixed(2);
        }
        ,this);
        
        this.hayCompra = ko.computed(function() {
            return parseFloat(this.total()) > 0;
        }
        ,this);
    },

    
    Categoria : function(id, nombre) {
        this._className = "Categoria";
        MODELO.Lista.apply(this,[id, nombre]);
        this.verArticulos = ko.observable(false);
        
        this.addArticulo = function (id, nombre, precioArticulo) {
            return this.addElemento(new MODELO.Articulo(id, nombre, precioArticulo,this));
        };
        
        var self = this;
        
        this.receiveArticulos = function () {            
            if (self.elementos().length > 0) {
                self.verArticulos(!self.verArticulos());    
            } else {
                var datos = {
                    idCategoria: self.id
                }
                $.ajax({
                    url: "./php/getCategoria.php",                
                    dataType: "json",
                    data: datos,
                    success: function (JSONArticulos) {
                        var articulos = JSONArticulos;
                        for (var i in articulos) {
                            self.addArticulo(articulos[i].idArticulo, articulos[i].nombreArticulo, articulos[i].precioArticulo);
                        }      
                        //console.log(self.elementos().length);
                        //Pruebas setInterval(function () {self.verArticulos(!self.verArticulos());},2000);                    
                        self.verArticulos(true);
                    }                
                });
            //console.log(tienda.categoriasArticulos.elementos().length);
            }
        }
        
    },

    Articulo : function(id, nombre, precioArticulo, categoria) {        
        MODELO.Elemento.apply(this,[id, nombre, categoria]);
        
        this._className = "Articulo";        
        this.precioArticulo = precioArticulo;
        this.cantidad = ko.observable("");
        this.subtotal = ko.computed(
            function() {
                return parseFloat(this.cantidad() * this.precioArticulo).toFixed(2);                
            },
            this);
            
        
    },

    Categorias : function() {        
        MODELO.Lista.apply(this,[0, null]);
        var self = this;
        this._className = "Categorias";
		
        this.addCategoria = function (id, nombre) {
            var categoria = new MODELO.Categoria(id, nombre);
            return this.addElemento(categoria);
        };
                
        this.getArticulo = function(idArticulo) {            
            return this.getElemento(idArticulo, "Articulo", true);
        };
        
        this.getCategoria = function (idCategoria) {
            return this.getElemento(idCategoria);
        };
        
        this.receiveCategorias = function () {      
            
            $.ajax({
                url: "./php/getCategorias.php",                
                dataType: "json",
                success: function (JSONCategorias) {                    
                    var categorias = JSONCategorias;                    
                    for (var i in categorias) {
                        self.addCategoria(categorias[i].idCategoria, categorias[i].nombreCategoria);                                
                    }     
                    
                }
            });
            
        }
        
    },

    

    Elemento : function(id, valor, padre) {
        this._className = "Elemento";
        this.id = id;
        this.valor = valor;
        
        this.padre = padre;

        this.equals = function(elemento) {
            return (this._className == elemento._className && this.id == elemento.id);
        }
        
    },

    Lista : function(id, valor, padre) {        	
        MODELO.Elemento.apply(this, [id, valor, padre]);
        this._className = "Lista";
        this.elementos = ko.observableArray();

        this.tam = function() {        
            return this.elementos().length;
        }
		
        this.addElemento = function(elemento) {
            //console.log(elemento);
            this.elementos.push(elemento);
            //console.log(this.elementos().length);
            return this;
        }

        this.getElemento = function(idElemento, _className, busquedaIntrospectiva) {
            var i = 0;
            var elemento = null;

            for (i in this.elementos()) {
                //console.log(this.elementos()[i]);
                if (this.elementos()[i].id == idElemento) {                    
                    if (!_className || this.elementos()[i]._className == _className) {                    
                        elemento = this.elementos()[i];
                        break;
                    }
                }

                if (!elemento) {                    
                    if (busquedaIntrospectiva && this.elementos()[i] instanceof MODELO.Lista) {
                        console.log(this.elementos()[i]);
                        elemento = this.elementos()[i].getElemento(idElemento, _className, true);
                        if (elemento) {
                            break;
                        }
                    }
                }

            }

            return elemento;
        }
        
    }


};



(function(){
    if('function' != typeof Function.prototype.inheritsFrom){
        Function.prototype.inheritsFrom = function(obj){
            this.prototype = obj.constructor == Function ? new obj : obj;
            this.prototype.constructor = this;
            return this;
        };
    }
})();




MODELO.Lista.inheritsFrom(MODELO.Elemento);
MODELO.Categoria.inheritsFrom(MODELO.Lista);
MODELO.Articulo.inheritsFrom(MODELO.Elemento);
MODELO.Categorias.inheritsFrom(MODELO.Lista);

var tienda;

function crearTienda() {
    tienda = new MODELO.Tienda("PC DAW");
    ko.applyBindings(tienda);
    applyCustomBindigs();
    applyCustomEvents();
    tienda.categoriasArticulos.receiveCategorias();
    
    console.log(tienda);
}

function applyCustomBindigs () {

    ko.bindingHandlers.slideVisible = {
        update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
            // First get the latest data that we're bound to
            var value = valueAccessor();
            var allBindings = allBindingsAccessor();
         
            // Next, whether or not the supplied model property is observable, get its current value
            var valueUnwrapped = ko.utils.unwrapObservable(value);
         
            // Grab some more data from another binding property
            var duration = allBindings.duracion || 400; // 400ms is default duration unless otherwise specified
            
            var divCategoria = $(element).prev();
            
            // Now manipulate the DOM element
            if (valueUnwrapped == true) {
                divCategoria.addClass("categoria_no_vacia").removeClass("categoria_vacia");
                $(element).slideDown(duration); // Make the element visible
            } else {
                $(element).slideUp(duration, function () {
                    divCategoria.removeClass("categoria_no_vacia").addClass("categoria_vacia");
                });   // Make the element invisible
                
            }
        }
    }
}

function applyCustomEvents () {      
    $("#basket").on("click", "a", function (event) {
        var context = ko.contextFor(this);                
        var articulo = context.$data;   
        var cantidad = $(this).val();        
        articulo.cantidad("");
        return false;
    }) ; 
}
function cambiarIdioma(idioma) {    
    
    var opts = {
        language: "es", 
        pathPrefix: "./js/idiomas",
        callback: function(data, defaultCallback){            
            literales = data;
            defaultCallback(data);
        }
    }    
    
    if (idioma) {
        opts.language = idioma;
    }
    
    $("[data-localize]").localize("literales", opts); 
}

function asignarEventosIdioma() {    
    
    $("[id^='flag']").click(        
        function () {            
            var idioma = $(this).attr("id").substr(-2);
            cambiarIdioma(idioma);
        }
        );
}

$(document).ready(
    function () {
        cambiarIdioma();
        asignarEventosIdioma();
        crearTienda();        
    }
    
    );
